using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;

namespace MyNamespace
{
    public class MultiUser : MultiLookup
    {
        #region Constructor
        public MultiUser(ItemBase p_parentItem, string p_fieldName, string p_lookupField, bool p_emptyAllowed)
            : base(p_parentItem, p_fieldName, p_parentItem.item.Web.Site.RootWeb.ID, p_parentItem.item.Web.Site.RootWeb.SiteUserInfoList.ID, p_lookupField, p_emptyAllowed) { }
        #endregion

        #region Methods
        public override void AddSelection(int newValueId)
        {
            SPFieldUser columnDef = (SPFieldUser)parentItem.item.ParentList.Fields.GetField(fieldName);
            SPFieldUserSelectionMode selectionMode = columnDef.SelectionMode;
            if (selectionMode == SPFieldUserSelectionMode.PeopleOnly)
            {
                User.Type type = GetReferncedUserType(newValueId);
                if (type == User.Type.SharePointGroup || type == User.Type.DomainGroup) throw new PointBridgeEx("User.ChangeSelection(): '" + fieldName + "' user is 'People Only' while newValidId = " + newValueId + " points to a group.");
            }
            base.AddSelection(newValueId);
        }
        public override object ToSPRepresentation()
        {
            if (_arr.Count == 0)
            {
                if (emptyAllowed == true) return null;
                else throw new PointBridgeEx("MiltiUser.ToSPRepresentation(): count is 0 while emptyAllowed is false");
            }

            Dictionary<int, bool> valueIds = new Dictionary<int, bool>();
            SPFieldUserValueCollection users = new SPFieldUserValueCollection();
            foreach (Lookup user in this)
            {
                if (user.isEmpty == true) throw new PointBridgeEx("MultiUser.ToSPRepresetation: User is empty. This should never happen.");
                if (valueIds.ContainsKey((int)user.valueId)) throw new PointBridgeEx("MultiUser.ToSPRepresentation(): Multi-User contains a duplicate valueId = " + (int)user.valueId);
                valueIds.Add((int)user.valueId, true);
                users.Add(new SPFieldUserValue(web, (int)user.valueId, user.valueString));
            }
            return users;
        }
        public override void InitFromSPRepresentation(object obj)
        {
            _arr.Clear();
            if (obj == null)
            {
                if (emptyAllowed == true) return;
                else throw new PointBridgeEx("MultiUser.InitFromSPRepresentation(): object is not initialized while emptyAllowed is false");
            }

            //multi lookup could come as a string or as an SPFieldLookupValueCollection
            //Format: "1;#Title;#2;#Title2"
            if (obj.GetType() == typeof(string))
            {
                string str = (string)obj;
                string[] separators = new string[1];
                separators[0] = ";#";
                string[] splits = str.Trim().Split(separators, StringSplitOptions.None);
                try
                {
                    for (int i = 0; i < splits.Length; i = i + 2)
                    {
                        int valueId = int.Parse(splits[i]);
                        string valueString = splits[i + 1];

                        User option = new User(this, valueId, valueString);
                        _arr.Add(option);
                    }
                }
                catch (Exception ex)
                {
                    throw new PointBridgeEx(string.Format("MultiUser.InitFromSPRepresentation(): SP representation string ({0} is in an incorrect format: {1})", str, ex.Message));
                }
            }
            else
            {
                SPFieldUserValueCollection users = (SPFieldUserValueCollection)obj;
                foreach (SPFieldUserValue rawUser in users)
                {
                    User user = new User(this, rawUser.LookupId, rawUser.LookupValue);
                    _arr.Add(user);
                }
            }

        }
        public static new int GetCountFromSPRepresentation(object obj)
        {
            if (obj == null) return 0;

            //multi lookup could come as a string or as an SPFieldLookupValueCollection
            //Format: "1;#Title;#2;#Title2"
            if (obj.GetType() == typeof(string))
            {
                string str = (string)obj;
                string[] separators = new string[1];
                separators[0] = ";#";
                string[] splits = str.Trim().Split(separators, StringSplitOptions.None);
                if (splits.Length % 2 != 0) throw new PointBridgeEx(string.Format("MultiUser.GetCountFromSPRepresentation(): SP representation string ({0} is in an incorrect format", str));
                return (int)splits.Length / 2;
            }
            else
            {
                SPFieldUserValueCollection users = (SPFieldUserValueCollection)obj;
                return users.Count;
            }

        }
        public User.Type GetReferncedUserType(int valueId)
        {
            string ct = (string)base.GetReferencedItem(valueId)["ContentType"];
            try
            {
                return (User.Type)Enum.Parse(typeof(User.Type), ct);
            }
            catch (Exception ex)
            {
                throw new PointBridgeEx("User.GetReferncedUserType(): Unknown user type: '" + ct + "': " + ex.Message);
            }
        }
        #endregion
    }
}
